#include <iostream>
#include "protocol.hpp"
#include <string>
#include <memory>
#include <ctime>
#include "Socket.hpp"
#include "InetAddr.hpp"

using namespace std;
using namespace socket_ns;
using namespace protocol_ns;

void Usage(string proc)
{
    cout << "Usage:" << proc << "server-ip server-port" << endl;
}

int main(int argc, char *argv[])
{
    // ./TcpClient ip port
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(-1);
    }
    string serverip = argv[1];                         // ip地址
    uint16_t serverport = stoi(argv[2]);               // 字符串转换整形，拿到端口号
    Factory factory;                                   // 获取请求
    unique_ptr<Socket> cli = make_unique<TcpSocket>(); // 创建tcp套接字对象
    InetAddr serveraddr(serverip, serverport);
    bool res = cli->BulidClientSocket(serveraddr); // 创建客户端需要的套接字
    string inbuffer;                               // 读取缓冲区
    while (res == true)
    {
        sleep(1);
        // 建立连接成功
        // 1.构建一个请求
        shared_ptr<Request> req = factory.BuildRequest();
        cout << "构建请求完成" << endl;

        // 2.序列化
        string send_str;
        req->Serialize(&send_str);

        cout << "序列化>>" << endl;
        cout << send_str;

        // 3.添加报头
        send_str = Encode(send_str);
        cout << "添加报头>>" << endl;
        cout << send_str;
        // 4.发送
        cli->Send(send_str);
        cout << "发送请求完成" << endl;
        // 5.接收
        int n = cli->Recv(&inbuffer);
        if (n <= 0)
        {
            break;
        }
        cout << "接收结果完成" << endl;

        cout << "接收到信息>>" << endl;
        cout << inbuffer;

        // 6.检验报文完整性并获取有效信息
        string package = Decode(inbuffer);
        if (package.empty() == true)
        {
            continue;
        }

        cout << "有效报文>>" << endl;
        cout << package;

        // 7.反序列化
        shared_ptr<Response> resp = factory.BuildResponse();
        resp->Deserialize(package);

        cout << "反序列化完成" << endl;
        // 拿到了结构化的应答数据

        // 8.打印结果
        cout << "本次处理结果>>" << endl;
        cout << "[结果:" << resp->_result << ",错误码:" << resp->_code << "]" << endl;
    }
    return 0;
}